package mailsystem;

import java.util.HashMap;
import java.util.List;
import java.util.Set;

import mailsystem.persistance.MailsystemPersistance;

/**
 * A mailbox contains messages that can be listed, kept or discarded.
 */
public class Mailbox {
	/**
	 * Creates Mailbox object.
	 * @param aMailBoxId the MailBox ID
	 * @param aPasscode
	 *           passcode number
	 * @param aGreeting
	 *            greeting string
	 * @param aName
	 * @param repo The repository
	 */
	public Mailbox(int aMailBoxId, String aPasscode, String aGreeting, String aName, MailsystemPersistance repo) {		
		boxId = aMailBoxId;
		passcode = aPasscode;
		greeting = aGreeting;
		name = aName;
		newMessages = new MessageQueue();
		keptMessages = new MessageQueue();
		contacts = new HashMap<String, Mailbox>();
		repository = repo;
		loadMessages();
	}

	private void loadMessages() {
		List<Message> msgs = repository.listAllNewMessages(this);
		
		for ( Message m : msgs )
		{
			newMessages.add(m);
		}
		
		msgs = repository.listAllKeptMessages(this);
		for ( Message m : msgs )
		{
			keptMessages.add(m);
		}	
	}
	
	public void loadContacts(List<Mailbox> theBoxes)
	{
		List<Mailbox> theContacts = repository.getAllContacts(this);
		
		for ( Mailbox c : theContacts )
		{			
			contacts.put(Integer.toString(c.getBoxId() + 1), theBoxes.get(c.getBoxId()));
		}
	}

	/**
	 * Check if the passcode is correct.
	 * 
	 * @param aPasscode
	 *            a passcode to check
	 * @return true if the supplied passcode matches the mailbox passcode
	 */
	public boolean checkPasscode(String aPasscode) {
		return aPasscode.equals(passcode);
	}
	
	/**
	 * Add a message to the mailbox.
	 * 
	 * @param aMessage
	 *            the message to be added
	 */
	public void addMessage(Message aMessage) {
		newMessages.add(aMessage);
		repository.addNewMessage(this, aMessage);
	}

	/**
	 * Add a mailbox contact to the mailbox.
	 * 
	 * @param aMailbox
	 *            to be added
	 */
	public void addContact(String number, Mailbox contact)
	{
		if (!contacts.containsKey(number) && contact != this)
		{
			contacts.put(number, contact);
			repository.addContact(this, contact);
		}
	}

	/**
	 * Get the current message.
	 * 
	 * @return the current message
	 */
	public Message getCurrentMessage() {
		if (newMessages.size() > 0)
			return newMessages.peek();
		else if (keptMessages.size() > 0)
			return keptMessages.peek();
		else
			return null;
	}

	/**
	 * Remove the current message from the mailbox.
	 * 
	 * @return the message that has just been removed
	 */
	public Message removeCurrentMessage() {
		if (newMessages.size() > 0)
		{
			repository.deleteNewMessage(getCurrentMessage());
			return newMessages.remove();
		}
		else if (keptMessages.size() > 0)
		{
			repository.deleteKeptMessage(getCurrentMessage());
			return keptMessages.remove();
		}
		else
			return null;
	}

	/**
	 * Save the current message
	 */
	public void saveCurrentMessage() {
		Message m = removeCurrentMessage();
		if (m != null)
		{
			repository.addKeptMessage(this, m);
			keptMessages.add(m);
		}
	}

	/**
	 * Change mailbox's greeting.
	 * 
	 * @param newGreeting
	 *            the new greeting string
	 */
	public void setGreeting(String newGreeting) {
		greeting = newGreeting;
		repository.updateMailbox(this);
	}

	/**
	 * Change mailbox's passcode.
	 * 
	 * @param newPasscode
	 *            the new passcode
	 */
	public void setPasscode(String newPasscode) {
		passcode = newPasscode;
		repository.updateMailbox(this);
	}

	/**
	 * Get the mailbox's greeting.
	 * 
	 * @return the greeting
	 */
	public String getGreeting() {
		return greeting;
	}
	
	public int getContactsCount() {
		return contacts.size();
	}

	private MessageQueue newMessages;
	private MessageQueue keptMessages;
	private int boxId;
	private String name;
	private String greeting;
	private String passcode;	
	private HashMap<String, Mailbox> contacts;
	private MailsystemPersistance repository;
	
	public String getName() {
		return name;
	}

	public void setName(String aName) {
		name = aName;
		repository.updateMailbox(this);
	}
	
	public int getBoxId()
	{
		return boxId;
	}
	
	public String getPasscode()
	{
		return passcode;
	}

	public void broadCastCurrentMessage() {		
		if (newMessages.size() > 0)
			for (Mailbox box : contacts.values())
				box.addMessage(newMessages.peek());
		else if (keptMessages.size() > 0)
			for (Mailbox box : contacts.values())
				box.addMessage(keptMessages.peek());
	}
	
	public void resendCurrentMessage(String list[])
	{
		if (newMessages.size() > 0)
			for ( String box : list )
				contacts.get(box).addMessage(newMessages.peek());
		else if (keptMessages.size() > 0)
			for ( String box : list )
				contacts.get(box).addMessage(keptMessages.peek());
		
	}
	
	public HashMap<String, String> getMailBoxList()
	{
		HashMap<String, String> resp = new HashMap<String, String>();
		
		Set<String> keys = contacts.keySet();
		
		for (String box : keys)
			resp.put(box, contacts.get(box).getName());
		
		return resp;
	}
	
	@Override	
	public boolean equals(Object obj) {
		Mailbox b2 = (Mailbox)obj;
		
		return boxId == b2.boxId &&
				name.equals(b2.name) &&
				greeting.equals(b2.greeting) &&
				passcode.equals(b2.passcode);
	}
}
